# -*- coding: utf-8 -*-
'''
Created on 2012-4-19

负责机器人动作的RequestHandler

@author: deadblue
'''
from cn._2dland import model, bot
from cn._2dland.handler import exception
from google.appengine.api import taskqueue
from google.appengine.ext import webapp
import time
import traceback

class ReachMaxRetryException(Exception):
    def __init__(self):
        pass

class ActionFailedException(Exception):
    def __init__(self):
        pass

class BotWorker(webapp.RequestHandler):
    def get(self):
        self.post()

    def post(self):
        username = self.request.get('account')

        acnt = None
        try:
            if not username:
                raise exception.InvalidRequestException()

            # 获取账户信息
            acnt = model.account.get_by_key_name(username)
            if acnt is None:
                raise exception.AccountNotFoundException

            # 判断重试次数是否超过最大值
            headers = self.request.headers
            if headers.has_key('X-AppEngine-TaskRetryCount'):
                retry_count = int(headers['X-AppEngine-TaskRetryCount'])
                if retry_count >= 115:
                    raise ReachMaxRetryException()

            # 实例化机器人
            u115 = bot.u115bot(username, acnt.password)
            
            # 登录
            if not u115.login():
                raise ActionFailedException()

            # 领取空间
            picksize = u115.pick()
            if picksize > 0:
                # 若领取空间成功，则记录日志
                log = model.picklog(account=username, size=picksize, time=long(time.time()))
                log.put()
            elif picksize < 0:
                raise ActionFailedException()

            # 记录最后活动时间
            acnt.last_active_time = long(time.time())

        except exception.AccountNotFoundException:
            # 无效账户，中止任务
            self.response.set_status(200)

        except ReachMaxRetryException:
            # 达到最大重试次数，设置账户状态为无效，并中止任务
            acnt.status = 2
            self.response.set_status(200)

        except ActionFailedException:
            # 动作执行失败，重试
            self.response.set_status(500)

        except Exception:
            # 其他异常，输出到后台
            traceback.print_exc()

        finally:
            if acnt is not None:
                acnt.put()

class BotManager(webapp.RequestHandler):

    def get(self):
        # 获取botqueue
        queue = taskqueue.Queue('botqueue')
        # 查找所有可用的账户
        acnts = model.account.all();
        acnts.filter('status = ', 0)
        # 创建任务
        for acnt in acnts:
            data = {'account':acnt.username}
            task = taskqueue.Task(url='/worker', method='POST', params=data)
            queue.add(task)

    def post(self):
        self.get()